﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Dot5Demo
{
    public partial class FrmRichTextBox : Form
    {
        public FrmRichTextBox()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            this.richTextBox1.WordWrap = false;
            this.richTextBox1.ScrollBars = RichTextBoxScrollBars.Both;
            this.richTextBox2.WordWrap = false;
            this.richTextBox2.ScrollBars = RichTextBoxScrollBars.Both;
            this.Load += FrmRichTextBox_Load;
            _textAlign = new DTTextAlignment(this.richTextBox2.CreateGraphics(), this.richTextBox2.Font);
            this.comboBox1.DataSource = Enum.GetValues(typeof(StringAlignment));
            this.comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
        }

        private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            _textAlign.Alignment = (StringAlignment)comboBox1.SelectedItem;
            this.richTextBox2.Text = _textAlign.GetResultString();
        }

        public double[] Values = new double[13]
        {
            1.0d,200.0d,30000.0d,4123456.789456d,5123456.789456d,
            0.1d,200.0d,56d,423456.78d,512345689565855d,
            15689890.0000056d,
            89890.000000000000000000056d,
            89898988880.00000000000000000000000056d,
        };
        public double[,] Data;
        public int[] MaxWidth { get; set; }
        private const int ColConut = 24;
        private const int RowCount = 300;


        private DTTextAlignment _textAlign;

        private LoadingForm loadingForm = new LoadingForm();
        private void FrmRichTextBox_Load(object sender, EventArgs e)
        {
            loadingForm.BackgroundWorkAction = GenerateDataEx;
            loadingForm.ShowDialog();
        }

        private void GenerateDataEx(LoadingForm frm)
        {
            frm.CurrentMsg = new KeyValuePair<int, string>(0, "产生数据");
            GenerateData();
            frm.CurrentMsg = new KeyValuePair<int, string>(0, "格式化数据");
            GenerateText();
            frm.CurrentMsg = new KeyValuePair<int, string>(0, "二维数组转表格");
            GenerateDataTable();
        }

        public void GenerateData()
        {
            Data = new double[ColConut, RowCount];
            MaxWidth = new int[ColConut];
            for (int i = 0; i < ColConut; i++)
            {
                for (int j = 0; j < RowCount; j++)
                {
                    //int k = new Random().Next(0, 12);
                    //Thread.Sleep(1);
                    Data[i, j] = Values[(Environment.TickCount + i + j) % 12];
                    //Data[i, j] = i + j * 0.000001d;
                    var len = Data[i, j].ToString().Length;
                    if ((len & 1) == 1)
                        len++;
                    if (len > MaxWidth[i])
                        MaxWidth[i] = len;
                }
                loadingForm.CurrentProgress = (int)(100.0f / ColConut * i);
            }
        }

        public StringBuilder builder = new StringBuilder();

        public void GenerateText()
        {
            builder.Clear();
            for (int i = 0; i < ColConut; i++)
            {
                builder.Append(MaxWidth[i].PadLeftRight(MaxWidth[i]));
            }
            builder.AppendLine("------------------");
            builder.AppendLine("------------------");
            builder.AppendLine("------------------");
            for (int j = 0; j < RowCount; j++)
            {
                for (int i = 0; i < ColConut; i++)
                {
                    loadingForm.CurrentProgress = (int)(RowCount / 100.0f * j);
                    builder.Append(Data[i, j].PadLeftRight(MaxWidth[i]));
                }
                builder.Append('\n');
            }
        }

        public void GenerateDataTable()
        {
            var dt = new DataTable();
            for (int i = 0; i < ColConut; i++)
            {
                dt.Columns.Add(i.ToString());
            }
            var row = dt.NewRow();
            for (int i = 0; i < ColConut; i++)
            {
                row[i] = "------";
            }
            for (int j = 0; j < RowCount; j++)
            {
                var r = dt.NewRow();
                for (int i = 0; i < ColConut; i++)
                {
                    r[i] = Data[i, j];
                }
                dt.Rows.Add(r);
                loadingForm.CurrentProgress = (int)(RowCount / 100.0f * j);
            }
            _textAlign.SetDataSource(dt);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Text = builder.ToString();
            this.richTextBox2.Text = _textAlign.GetResultString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var fm = new FrmMarkDown();
            fm.Data = Data;
            fm.Cols = ColConut;
            fm.Rows = RowCount;
            fm.ShowDialog();
        }
    }

    public static class StringExt
    {
        public static string PadLeftRight(this double v, int maxW, char ch = ' ')
        {
            return v.ToString().PadLeftRight(maxW, ch);
        }
        public static string PadLeftRight(this int v, int maxW, char ch = ' ')
        {
            return v.ToString().PadLeftRight(maxW, ch);
        }

        public static string PadLeftRight(this string str, int maxW, char ch = ' ')
        {
            bool odd = false;
            if (str.Length < maxW)
            {
                var dc = maxW - str.Length;
                odd = (dc & 1) == 1;
                if (odd)
                    dc++;
                var d = dc / 2;
                str = str.PadLeft(str.Length + d, ch);
                str = str.PadRight(str.Length + d, ch);
            }
            var stre = ">\t\t";
            if (!odd)
                stre += "\t";
            return "<" + str + stre;
        }
    }
}
